package main

import (
	"config-client-v1/utils/tools"
	"flag"
	"fmt"
	"github.com/simonvetter/modbus"
	"time"
)

var client *modbus.ModbusClient

// Modbus RTU,TCP 客户端 poll端代码
// 扫描点位信息和点位写入
var portName *string
var protocol *string
var scanRate *int

func main() {
	defer tools.Pause()
	portName = flag.String("port", "127.0.0.1:502", "串口名或ip:port")
	protocol = flag.String("protocol", "tcp", "协议 rtu或tcp")
	scanRate = flag.Int("scan_rate", 3000, "扫描频率(ms)")
	flag.Parse()
	if *portName == "" {
		fmt.Printf("port cant bt empty\n")
		return
	}
	if *protocol == "" {
		fmt.Printf("protocol cant bt empty\n")
		return
	}
	if *scanRate <= 0 {
		*scanRate = 1000
		return
	}
	if *protocol != "rtu" && *protocol != "tcp" {
		fmt.Printf("protocol must be one of RTU, TCP\n")
		return
	}
	var err error
	url := *protocol + "://" + *portName
	url = "tcp://192.168.1.131:504"
	fmt.Printf("connecting url: %s\n", url)
	if *protocol == "rtu" {
		// RTU 串口 设备/总线
		client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:      url,
			Speed:    9600,               // default
			DataBits: 8,                  // default, optional
			Parity:   modbus.PARITY_NONE, // default, optional
			StopBits: 1,                  // default if no parity, optional
			Timeout:  300 * time.Millisecond,
		})
	} else {
		// TCP 端点
		client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:     url,
			Timeout: 1 * time.Second,
		})
	}

	if err != nil {
		fmt.Printf("modbus.NewClient error %s \n", err.Error())
		return
	}
	err = client.Open()
	if err != nil {
		fmt.Printf("client.Open error %s \n", err.Error())
		return
	}
	defer client.Close()
	//client.SetEncoding(modbus.LITTLE_ENDIAN, modbus.LOW_WORD_FIRST)
	fmt.Printf("【%s】%s\n", "modbus连接成功", url)
	for {
		buffer := make([]byte, 0)
		err0 := client.SetUnitId(43)
		if err0 != nil {
			fmt.Printf("【%s】SetUnitId error %s\n", tools.GetNow(), err0.Error())
		}
		err2 := client.WriteCoils(15, []bool{true, true, true, true, true, true, true, true, true})
		//buffer2, err2 := client.ReadCoils(10, 8)
		if err2 != nil {
			fmt.Printf("【%s】 WriteCoil error %s\n", tools.GetNow(), err2.Error())
		} else {
			fmt.Printf("【%s】 buffer=%v\n", tools.GetNow(), buffer)
			//f1 := tools.ByteToFloat32(buffer[4:8], "big")
			//f2 := tools.ByteToFloat32(buffer[8:12], "big")
			//fmt.Printf("【%s】温度: %.2f℃, 湿度: %.2f%%\n", tools.GetNow(), f1, f2)
		}
		time.Sleep(time.Duration(*scanRate) * time.Millisecond)
	}
}

// ReadRegister 读取单个寄存器
func ReadRegister() {
	for {
		time.Sleep(3 * time.Second)
		reg16, err := client.ReadRegister(10, modbus.HOLDING_REGISTER)
		if err != nil {
			fmt.Printf("client.ReadRegister error %s \n", err.Error())
			continue
			// error out
		} else {
			// use value
			fmt.Printf("[%s] value: int16=%v , uint16=%v\n", tools.GetNow(), int16(reg16), reg16)
		}
	}
}

// GetTH 读取多个连续寄存器
func GetTH() (v [2]float32, err error) {
	var fl32s []float32
	fl32s, err = client.ReadFloat32s(2, 2, modbus.HOLDING_REGISTER)
	if err != nil {
		fmt.Printf("client.ReadRegister error %s \n", err.Error())
		return
	} else {
		//fmt.Printf("[%s] value: fl32s=%v\n", tools.GetNow(), fl32s)
		v[0] = fl32s[0]
		v[1] = fl32s[1]
		return
	}
}

// ReadRegisters 读取多个连续寄存器
// addr 寄存器起始地址 quantity 要读取的寄存器数量
func ReadRegisters(addr uint16, quantity uint16) {
	for {
		time.Sleep(3 * time.Second)
		var reg16s []uint16
		reg16s, err := client.ReadRegisters(addr, quantity, modbus.HOLDING_REGISTER)
		if err != nil {
			fmt.Printf("client.ReadRegister error %s \n", err.Error())
			continue
			// error out
		} else {
			// use value
			fmt.Printf("[%s] value: uint16=%v\n", tools.GetNow(), reg16s)
		}
	}
}

// ReadFloat32s 读取多个连续寄存器
func ReadFloat32s(addr uint16, quantity uint16) {
	for {
		time.Sleep(3 * time.Second)
		var fl32s []float32
		fl32s, err := client.ReadFloat32s(addr, quantity, modbus.HOLDING_REGISTER)
		if err != nil {
			fmt.Printf("client.ReadRegister error %s \n", err.Error())
			continue
		} else {
			// use value
			fmt.Printf("[%s] value: fl32s=%v\n", tools.GetNow(), fl32s)
		}
	}
}

func writeTest() {
	// 连续写入4个寄存器, 共8个字节
	err := client.WriteBytes(0, []byte{
		0x01, 0x02, 0x03, 0x04,
		0x05, 0x06, 0x07, 0x08,
	})
	if err != nil {
		fmt.Printf("WriteBytes error: %s\n", err.Error())
	}
	// 连续写入2个寄存器, 共8个字节
	err = client.WriteFloat32s(10, []float32{
		3.14,
		-783.22,
	})
	if err != nil {
		fmt.Printf("WriteFloat32s error: %s\n", err.Error())
	}
}
